/*package gm.broken;

trait GenericComp requires (CoreConvsComp with GenericComp) {
  trait Plus[a,b]
    case class Inl[a,b](el: a) extends Plus[a,b]
    case class Inr[a,b](el: b) extends Plus[a,b]

  case class Iso[t,dt](fromData: dt=>t, toData: t=>dt)

  trait Rep[g <: TypeFun1, t] {           
    type Res[t] = g{type a=t}        
    def rep: Res[t] // TODO translate constraint Generic g  (not necessary??)
  }
  
 
  trait Generic[gg <: TypeFun1]  {
    type MyRep[t] = Rep[gg, t] 
    type Res[t] = gg{type a=t}
             
    def unit: Res[Unit]
    def plus[aa, b](implicit c1: aa=>MyRep[aa], c2: b=>MyRep[b]): Res[Plus[MyRep[aa], MyRep[b]]]
    def pair[aa, b](implicit c1: aa=>MyRep[aa], c2: b=>MyRep[b]): Res[Pair[MyRep[aa], MyRep[b]]]
    def datatype[aa, b](iso: Iso[aa,b])(implicit c1: aa=>MyRep[aa]): Res[MyRep[b]]
    def char: Res[Char]
    def int: Res[Int]
  
    val convs: TConvs{type g=gg} = makeConvs(this)
  }
}


trait ShowBinComp requires (CoreConvsComp with GenericComp with ShowBinComp) {
  type Bin = List[Bit]
  trait Bit
    case object _0 extends Bit
    case object _1 extends Bit
                  
  trait TShowBin extends TypeFun1{
    val apply: a => Bin 
  }

  def bits(n: Int, x: Int): Bin = if(n==0) Nil else {if((x&1)==1) _1 else _0} :: bits(n-1,x>>1)
    
  class ShowBin extends Generic[TShowBin] {
    def showBin[t](x: t)(implicit c: t=>MyRep[t]): Bin = x.rep.apply(x) 

    // TODO: lift tsb to Generic? -- may be too restrictive..
    def tsb[aa](f: aa => Bin) = new TShowBin{type a=aa; val apply = f} 
    
    def unit = tsb ((x: Unit) => Nil) 
    def plus[aa, b](implicit c1: aa=>MyRep[aa], c2: b=>MyRep[b]) = tsb (
        (x: Plus[aa, b]) => x match {
          case Inl(el) => _0 :: showBin(el)
          case Inr(el) => _1 :: showBin(el)
        }) 
    
    def pair[aa, b](implicit c1: aa=>MyRep[aa], c2: b=>MyRep[b]) = tsb (
        (x: Pair[aa, b]) => showBin(x._1) ::: showBin(x._2))
    
    def datatype[aa, b](iso: Iso[aa,b])(implicit c1: aa=>MyRep[aa]) = tsb (
        (x: b) => showBin(iso.fromData(x)))
    
    def char = tsb ((x: Char) => bits(7,x))
    def int = tsb ((x: Int) => bits(16,x))
  }
}

trait CoreConvsComp requires (CoreConvsComp with GenericComp) {
  type TConvs <: CoreConvs
  def makeConvs[gg <: TypeFun1](theGen: Generic[gg]): TConvs{type g=gg}

  trait Convs {
    type g <: TypeFun1
    type MyRep[t] = Rep[g, t]                 

    val generic: Generic[g]
    def mr[t](f: Generic[g]=>g{type a=t}) = new MyRep[t]{def rep: Res[t]=f(generic)}    
  }

  trait CoreConvs requires TConvs extends Convs { 
    implicit def unit2rep(u: Unit): MyRep[Unit] = mr (.unit)
    implicit def int2rep(i: Int): MyRep[Int] = mr (.int)
    implicit def char2rep(c: Char): MyRep[Char] = mr (.char)
    implicit def pair2rep[t, u](p: Pair[t, u])(implicit c1: t=>MyRep[t], c2: u=>MyRep[u]): MyRep[Pair[MyRep[t], MyRep[u]]] 
        = mr (.pair(c1, c2)) // TODO: why do c1, c2 have to be passed explicitly? -- if I inline mr, it's not necessary
    implicit def plus2rep[t, u](p: Plus[t, u])(implicit c1: t=>MyRep[t], c2: u=>MyRep[u]): MyRep[Plus[MyRep[t], MyRep[u]]]  
        = mr (.plus(c1, c2))
  }
}

trait ListConvComp requires (CoreConvsComp with ListConvComp with GenericComp) {
  type TConvs <: (CoreConvs with ListConv)
  
  trait ListConv requires TConvs extends Convs {
    def fromList[t](l: List[t]): Plus[Unit, Pair[t, List[t]]] = l match {
      case Nil => Inl(())
      case x :: xs => Inr(Pair(x, xs))
    }
    
    def toList[t](l: Plus[Unit, Pair[t, List[t]]]): List[t] = l match {
      case Inl(())=> Nil 
      case Inr(Pair(x, xs)) => x :: xs 
    }
    
    implicit def list2rep[t](l: List[t])(implicit c: t=>MyRep[t]): MyRep[List[MyRep[t]]]
      = mr (.datatype(Iso(fromList, toList)))  // TODO: have to supply [t], why?
  }     
}

object deploy extends GenericComp with ShowBinComp with CoreConvsComp with ListConvComp {
  type TConvs = CoreConvs with ListConv
  def makeConvs[gg <: TypeFun1](theGen: Generic[gg]) = new CoreConvs with ListConv{type g=gg; val generic = theGen}
}
*/
// testpad:
// {val sb = new ShowBin(); import sb.convs._; sb.showBin(3)}
// {val sb = new ShowBin(); import sb.convs._; sb.showBin(List(3,5))}
//{val sb = new ShowBin(); import sb.convs._; sb.showBin("Lisa".toList)}
//{val sb = new ShowBin(); import sb.convs._; sb.showBin("Lisa")} // --> string2seq is not chained with list2rep